#pragma once
#include <memory>

#include "../CachePolicy.h"
#include "LruPart.h"
#include "LfuPart.h"


namespace Cache
{
template<typename K, typename V>
class ArcCache :public CachePolicy<K,V>
{
private:
    size_t _capacity;
    size_t _changeCountFlag;
    std::unique_ptr<LruPart<K,V>> _lruPart;
    std::unique_ptr<LfuPart<K,V>> _lfuPart;

public:
    explicit ArcCache(size_t capacity = 10, size_t changeCountFlag = 2)
        :_capacity(capacity)
        , _changeCountFlag(changeCountFlag)
        ,_lruPart(std::make_unique<LruPart<K,V>>(capacity, changeCountFlag))
        ,_lfuPart(std::make_unique<LfuPart<K,V>>(capacity, changeCountFlag))
    {}

    ~ArcCache() override = default;

    void put(K key, V value) override
    {
        checkGhostCaches(key);

        //检查lfu部分缓存有没有这个数据
        bool inLfu = _lfuPart->contain(key);
        //更新lru部分的缓存
        _lruPart->put(key, value);
        // 如果 LFU 部分存在该键，则更新 LFU 部分
        if (inLfu)
        {
            _lfuPart->put(key, value);
        }

    }

    bool get(K key, V& value) override
    {
        checkGhostCaches(key);

        bool shouldChangeFlag = false;
        if (_lruPart->get(key, value,shouldChangeFlag))
        {
            if (shouldChangeFlag)
            {
                _lfuPart->put(key, value);
            }
            return true;
        }
        return _lfuPart->get(key, value);
    }

    bool remove(K key, V& value) override
    {
        return false;
    }

private:
    bool checkGhostCaches(K key)
    {
        bool inGhost = false;
        if (_lruPart->checkGhost(key))
        {
            if (_lfuPart->decreaseCapacity())
            {
                _lruPart->increaseCapacity();
            }
            inGhost = true;
        }
        else if (_lfuPart->checkGhost(key))
        {
            if (_lruPart->decreaseCapacity())
            {
                _lfuPart->increaseCapacity();
            }
            inGhost = true;
        }
        return inGhost;
    }
};




}
